package com.mydemo.admin.service.impl;

import com.mydemo.admin.service.ISysUserService;
import com.mydemo.common.Constant;
import com.mydemo.common.exception.captcha.CaptchaException;
import com.mydemo.common.exception.user.UserException;
import com.mydemo.common.pojo.*;
import com.mydemo.common.utils.JWTUtils;
import com.mydemo.common.utils.RedisUtils;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

/**
 * @author Last_Island
 * @version 1.0
 */
@Service
public class SysLoginService {

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private SysCaptchaService sysCaptchaService;

    @Autowired
    private JWTUtils jwtUtils;

    @Autowired
    private RedisUtils redisUtils;

    @Value("${token.expireTime}")
    private int expireTime;

    @Resource
    private AuthenticationManager authenticationManager;

    /**
     * 登录
     *
     * @param loginBody 登录信息
     * @return
     */
    public String login(LoginBody loginBody) {
        validateField(loginBody);
        validateCaptcha(loginBody);
        String username = loginBody.getUsername(), password = loginBody.getPassword();
        UsernamePasswordAuthenticationToken authRequest = UsernamePasswordAuthenticationToken.unauthenticated(username,
                password);
        Authentication authenticate = authenticationManager.authenticate(authRequest);
        SecurityContextHolder.getContext().setAuthentication(authenticate);
        LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
        String token = jwtUtils.createToken(loginUser);
        String key = Constant.SYS_USER_TOKEN + token;
        // 缓存token
        redisUtils.setCacheObject(key,loginUser,expireTime, TimeUnit.MINUTES);
        return token;
    }

    /**
     * 登出
     *
     * @return
     */
    public RespResult logout(String token) {
        String key = Constant.SYS_USER_TOKEN + token;
        if (redisUtils.deleteObject(key))
            return RespResult.success("退出成功");
        return RespResult.error(300,"退出失败");
    }

    /**
     * 注册
     *
     * @param registerBody 注册用户信息
     * @return
     */
    public RespResult register(RegisterBody registerBody) {
        validateField(registerBody);
        validateCaptcha(registerBody);
        SysUser sysUser = new SysUser();
        sysUser.setUsername(registerBody.getUsername());
        sysUser.setPassword(registerBody.getPassword());
        sysUser.setEmail(registerBody.getEmail());
        return sysUserService.addUser(sysUser)? RespResult.success("注册成功") : RespResult.error(300,"注册失败");
    }


    /**
     * 验证字段
     *
     * @param
     */
    private void validateField(String username, String password) {
        if (!StringUtils.hasText(username)) {
            throw new UserException("用户名不能为空");
        } else if (password == null) {
            throw new UserException("密码不能为空");
        } else if (password.length() < 6) {
            throw new UserException("密码长度不得小于6位");
        }
    }

    /**
     * 验证字段
     *
     * @param user
     */
    private void validateField(LoginBody user) {
        String username = user.getUsername(),
                password = user.getPassword();
        validateField(username, password);
        if (user instanceof RegisterBody) {
            String email = ((RegisterBody) user).getEmail();
            if (email == null) {
                throw new UserException("邮箱不能为空");
            } else if (!email.matches("^[a-zA-Z0-9!#$%&'*+/=?^_`{|}~.-]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)+$")) {
                throw new UserException("邮箱格式不正确");
            }
        }
    }

    /**
     * 验证验证码
     *
     * @param user
     */
    private void validateCaptcha(LoginBody user) {
        String code = user.getCode();
        if (!StringUtils.hasText(code)) {
            throw new CaptchaException("验证码不能为空");
        } else if (user instanceof RegisterBody) {
            String email = ((RegisterBody) user).getEmail();
            sysCaptchaService.checkCaptcha(email, code);
        } else {
            String uuid = user.getUuid();
            sysCaptchaService.checkCaptcha(uuid, code);
        }
    }
}
